Skip to content

feat(payments): let clients see their subscription tier - #926

Open
Priyanshubhartistm wants to merge 4 commits into
cameri:mainfrom
Priyanshubhartistm:feat/subscription-client-status
Open

Priyanshubhartistm wants to merge 4 commits into
cameri:mainfrom
Priyanshubhartistm:feat/subscription-client-status

Conversation

@Priyanshubhartistm

Copy link
Copy Markdown
Collaborator

Description

Builds on the subscription lifecycle (#909). Nothing changes unless payments.enabled is true and payments.subscriptionPlans is non-empty.

  • NIP-11: the plans are advertised under fees.subscription, one entry per plan with amount in msats, unit, and period in seconds (the standard NIP-11 shape), plus id, which is what a client sends as planId to POST /invoices, and description when the plan has one. limitation.restricted_writes is now true when plans are in use, since a subscription is what lets a pubkey write even without an admission fee.
  • GET /subscriptions/status?pubkey=<hex or npub> returns the pubkey's planId, status, active, currentPeriodEnd and accessEndsAt (ISO dates, null when it never ends). active is judged from the dates, as the write gate does, so grace counts and a lapsed subscription the sweep has not reached yet does not. A pubkey with no subscription gets nulls and active: false. It answers 400 for an invalid pubkey and 404 while plans are off, and is counted against limits.invoice.rateLimits under its own key.
  • CONFIGURATION.md describes both.

Related Issue

Closes #925

Motivation and Context

The endpoint is public, like /admissions/check/:pubkey, and only reports what the relay already enforces for that pubkey.

Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
@changeset-bot

changeset-bot Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e34f566

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
nostream Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@greptile-apps

greptile-apps Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The PR adds public subscription details to two client-facing relay paths.

Add CORS headers before merging so browser clients on other sites can use the new endpoint.

Findings

  1. P1 Browser clients cannot read subscriptions ▶
  2. P2 Uppercase npubs are rejected ▶

Summary

The PR advertises subscription plans in NIP-11 and adds a public endpoint for subscription status.

  • NIP-11 lists subscription plans and marks writes as restricted.
  • Clients can check a pubkey’s subscription status and access dates.

Diagram

sequenceDiagram
  participant Client
  participant Relay
  participant Repository
  Client->>Relay: "GET /subscriptions/status?pubkey=..."
  Relay->>Relay: Check limits, plans, and pubkey
  Relay->>Repository: findByPubkey(pubkey)
  Repository-->>Relay: Subscription or no row
  Relay->>Relay: Calculate access and end dates
  Relay-->>Client: Plan, status, active, and dates
Loading

Reviews (4) · Last reviewed commit: "Merge branch 'main' into feat/subscripti..." · Reviewed by Greptile

Comment thread src/controllers/subscriptions/get-subscription-status-controller.ts Outdated
Comment thread src/controllers/subscriptions/get-subscription-status-controller.ts Outdated
Comment thread CONFIGURATION.md Outdated
@coveralls

coveralls commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 40026647273

Warning

No base build found for commit c40e570 on main.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 75.627%

Details

  • Patch coverage: 2 uncovered changes across 2 files (81 of 83 lines covered, 97.59%).

Uncovered Changes

File Changed Covered %
src/controllers/subscriptions/get-subscription-status-controller.ts 52 51 98.08%
src/factories/controllers/get-subscription-status-controller-factory.ts 7 6 85.71%
Total (6 files) 83 81 97.59%

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 11366
Covered Lines: 8984
Line Coverage: 79.04%
Relevant Branches: 5895
Covered Branches: 4070
Branch Coverage: 69.04%
Branches in Coverage %: Yes
Coverage Strength: 801.12 hits per line

💛 - Coveralls

…e not 32 bytes

Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
return raw
}

if (/^npub1/.test(raw)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Uppercase npubs are rejected

A valid all-uppercase NPUB1... gets a 400 response because parsePubkey checks the prefix with a case-sensitive regex. Clients using this encoding cannot check their subscription, even though fromNpub already supports it. Make the prefix check case-insensitive and add an endpoint test for an uppercase npub.

Suggested change
if (/^npub1/.test(raw)) {
if (/^npub1/i.test(raw)) {

@cameri

cameri commented Oct 23, 2026

Copy link
Copy Markdown
Owner

@Priyanshubhartistm Let's please fix the issue flagged by Greptile

}
: { pubkey, planId: null, status: null, active: false, currentPeriodEnd: null, accessEndsAt: null }

response.status(200).setHeader('content-type', 'application/json; charset=utf8').send(body)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Browser clients cannot read subscriptions

/subscriptions/status returns no Access-Control-Allow-Origin header, and neither the app nor the router adds one. Browser clients hosted on another site therefore cannot read the response or show the user's subscription tier, even when the request succeeds. Add CORS headers to this public endpoint, including its error responses.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(payments): let clients see their subscription tier

3 participants